/**
 * Copyright 2005 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.edi.proxy.component
{
	import com.edi.runtime.component.EDIApplication;
	import com.edi.runtime.component.EDIDataSource;
	import com.edi.runtime.component.EDIProgressWindow;
	import com.string.StrUnit;
	
	import mx.collections.ArrayCollection;
	import mx.controls.Alert;
	import mx.messaging.messages.ErrorMessage;
	import mx.messaging.messages.HTTPRequestMessage;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.http.mxml.HTTPService;
	
	/**
	 * http代理组件 负责信息的发送 
	 * @author Administrator
	 * var proxy:HttpProxy=new HttpProxy();
	 *		var param:EPOParam = new EPOParam("select * from table where vc_id=?");
	 *		param.setString(1,value);
	 *		param.dsName = "show_notice";
	 *		proxy.addPoParam(param);
	 *		proxy.resultCallback=function(event:HttpProxyResult):void
	 *		{
	 *			var xmlList:XMLList=event.getPoResultByDsName("show_notice").table.children();
	 *			...	
	 *		}
	 *	    proxy.send();
	 * 
	 */	
	
	public class HttpProxy implements IEDIProxy,ITips
	{
		private var poParams :ArrayCollection; 
		private var _caller:String; 
		private var _params:Array;
		private var _obj:Object;
		private var _resultCallback:Function=null;
		private var _faultCallBack:Function=null;
		private var _tips:Array;
		private var _appName:String;
		private var _sessionId:String;
		private var _datasource:EDIDataSource;
		/**
		 * 发送目标的url 
		 */		
		public var url:String;
		/**
		 * 是否自动分发 
		 */		
		public var autoDispatch:Boolean;
		/**
		 * url后面加的参数 
		 */		
		public var param:String="";
		/**
		 * 是否全部转换成xml ，若为false 则字段内的值读取时需要使用到com.string.StrUnit.replaceAllToXML()方法进行再次转换。
		 */		
		public var replaceAllToXML:Boolean=true;
		public var successMessage:String = null;
		public var failedMessage:String = null;
		private var pw:EDIProgressWindow;
		public var proxyPool:Boolean=false;
		
		/**
		 * 构造 http代理 
		 * @param appName 应用名称
		 * @param sessionId sessionID 通常有服务器参数获取 例如：EDIApplication.sessionId = Application.application.parameters.ediSessionId;
		 * @param autoDispatch  是否自动分发
		 * @param datasource 自动分发到的数据源
		 * 
		 */		
		public function HttpProxy(appName:String=null,autoDispatch:Boolean=false,datasource:EDIDataSource=null)
		{
//			this.ediDs = ediDs;
//			this.pos = new ArrayCollection();
			this.poParams = new ArrayCollection();
			if (appName == null){
				this._appName = EDIApplication.appName;
			}else{
				this._appName = appName;
			}
//			if (sessionId == null){
//				this._sessionId = EDIApplication.sessionId;
//			}else{
//				this._sessionId = sessionId;
//			}
			_params=new Array();
			this.autoDispatch = autoDispatch;
			this._datasource = datasource;
			pw=new EDIProgressWindow;
		}
		
		public function set caller(value:String):void{_caller=value;}
		public function get caller():String{return _caller==null?"":_caller;} 
		
		/**
		 *  当 HTTPService 调用成功返回时调度；
		 * @param value 回调函数 必须是function(event:HttpProxyResult):void{...}
		 * 返回结构将通过event获得,具体请参考HttpProxyResult对象。
		 * 
		 */		
		public function set resultCallback(value:Function):void
		{
			_resultCallback=value;
		}
		
		/**
		 * 当 HTTPService 调用失败时调度；当state为非0时 
		 * @param value 回调函数
		 * 
		 */		
		public function set faultCallBack(value:Function):void
		{
			_faultCallBack=value;
		}
		
		/**
		 * 请求发送 
		 * 协议如下：
		 * <ds>
		 *	  <caller/>
		 *	  <appName>应用名</appName>
		 *	  {<POParam> </POParam>} 具体的poparam对象所生成的协议
		 *	</ds>
		 * param:successMessage 操作成功后返回信息
		 * param:failedMessage  操作失败后返回信息
		 */		
		public function send(successMessage:String=null,failedMessage:String=null):void{
			var http:HTTPService = new HTTPService();
			var i:int;
			var sendXml:XML=new XML(<ds />);
			var posXml:XML;
			
			this.successMessage = successMessage;
			this.failedMessage = failedMessage;
			 
			//http.url = url;//ediDs.appName;
			if(EDIApplication.debug)
			{
				http.url = EDIApplication.path+EDIApplication.appName+".app";
			}
			else
			{
				if (this.url == null || this.url=="")
				{
					if(this._appName!=null || this._appName!="")
					{
						http.url = this._appName+".app";
					}
					else
					{
						http.url = EDIApplication.appName +".app";
					}
				}
				else 
					http.url = url;
			}
			//mx.controls.Alert.show("_appName : "+this._appName);
			//mx.controls.Alert.show("httpurl:"+http.url);
			http.resultFormat = "xml";
			http.method=HTTPRequestMessage.POST_METHOD;
			http.useProxy = false;
			http.addEventListener(ResultEvent.RESULT,resultHandle);
			http.addEventListener(ResultEvent.RESULT,showSucessMessage);
			http.addEventListener(FaultEvent.FAULT,faultHandle);
			http.addEventListener(FaultEvent.FAULT,showFailedMessage);
			sendXml.appendChild(<caller>{caller}</caller>);
			sendXml.appendChild(<appName>{this._appName}</appName>);
			
			for(i=0;i<poParams.length;i++)
			{ 
				sendXml.appendChild(poParams[i].toXml());
			}
			poParams.removeAll();
			var obj:Object=new Object();
			obj.ediPara=sendXml.toXMLString();
			trace(http.url);
			trace(sendXml.toXMLString());
			EDIApplication.outputDebug("<b>url:"+http.url+"</b><br>",false);
			EDIApplication.outputDebug("<b>appName:"+EDIApplication.appName+"</b><br>",false);
			EDIApplication.outputDebug("<b>appId:"+EDIApplication.appId+"</b><br>",false);
//			EDIApplication.outputDebug("<b>sessionId:"+EDIApplication.sessionId+"</b><br>",false);
			
			EDIApplication.outputDebug(sendXml.toXMLString());
			obj.ediSessionId = this._sessionId;
			trace(obj.ediSessionId);
			http.send(obj); 
			pw.show();
			//http.send(sendXml);
		}
		 
		
		private function cdata(value:String):XML
		{
			return  new XML("<![CDATA[" + value + "]]>");
		}
		
	
		/**
		 * 添加 poparam对象.
		 * @param poParam poparam对象,如epoparam,spoparam,wpoparam,tpoparam
		 * 
		 */		
		public function addPoParam(poParam:POParam):void{
			this.poParams.addItem(poParam);
		}
		
		protected function resultHandle(event:ResultEvent):void{
			var processState:Boolean = false;
			try
			{
				pw.close();
				trace("返回值"); 
				var result:String=event.result.toString();
				trace(result);
//				Alert.show("result: "+result);
				EDIApplication.outputDebug("return ---:<br/>"+result);
				if(replaceAllToXML)
				{
					result=StrUnit.replaceAllToXML(result);
				}
				else
				{
					result=StrUnit.replace(result,"]]&gt;","]]>");
					result=StrUnit.replace(result,"&lt;![CDATA[","<![CDATA[");
				}
				trace("replace after ---:");
				trace(result);
				
				
				//trace(XML(result).toXMLString());
				var xml:XML=XML(result);
				
				//trace("返回内容："+unescape(xml.toXMLString()));
				var dbXml:XML;
				var poResult:PoResult;
				var hpe:HttpProxyResult=new HttpProxyResult();
				hpe.state=xml.state[0];
				if(hpe.state=="1")
				{
					var xList:XMLList=xml.result;
					var obj:Object;
					var i:int;	
					for(i=0;i<xList.length();i++)
					{
						//将每个返回表 进行分解
						poResult=new PoResult(xList[i]);
						if (!poResult.state){
							EDIApplication.alert(poResult.errorInfo,"返回服务器端错误："+poResult.dsName);
							processState = false;
							break;
						}else{
							processState = true;
							
						}
						if (processState){
							EDIApplication.outputDebug("当前处理状态为：--真");
						}else{
							EDIApplication.outputDebug("当前处理状态为：--假");
						}
						
						hpe.addPOResult(poResult);
					}	
				}
				else
				{
					if(xml && null!=xml.errorInfo[0] && xml.errorInfo[0]!=""){
						EDIApplication.alert(xml.errorInfo[0]);
					}else{
						EDIApplication.alert("网页已超期，请重新登录!","温馨提示");
					}
				}								
			}
			catch(e:ErrorMessage)
			{
				mx.controls.Alert.show("数据交互失败，错误编号："+e.messageId);
				trace("-----------");
				trace("系统级错误：事件：ResultEvent 方法：resultHandle"+e.messageId);
				EDIApplication.outputDebug("系统级错误：事件：ResultEvent 方法：resultHandle+<br/>"+e.messageId);
				trace("-----------");
				EDIApplication.alert("无法连接至服务器，请检查网络连接！","温馨提示");
			}
			
			if(processState==false)
			{
				EDIApplication.outputDebug("本次返回值总体处理状态为失败：=false");
				if( _faultCallBack!=null)
				{
					_faultCallBack.call();
				}
				return;
			}
			if (processState){
				EDIApplication.outputDebug("当前处理状态为：--真");
			}else{
				EDIApplication.outputDebug("当前处理状态为：--假");
			}
			if (_datasource == null){
				EDIApplication.outputDebug("当前数据源为空");
			}else{
				EDIApplication.outputDebug("当前数据源不为空");
			}
			if (processState==true &&  _datasource!=null){
				EDIApplication.outputDebug("开始分发数据源数据....");
				dispatchDatasource(hpe);			
			}else{
				EDIApplication.outputDebug("未分发数据源数据....");
			}
			if(processState && _resultCallback!=null){
				_resultCallback(hpe);
			}
			if(proxyPool)
			{
				HttpProxyPool.freeHttpProxy(this);
			}
		}
		
		private function dispatchDatasource(pr:HttpProxyResult):void{
			while(pr.poNext()){
				var poResult:PoResult = pr.currentPoResult;
				if (poResult.state){
					EDIApplication.outputDebug("为数据源增加一个数据表:"+poResult.dsName);
					this._datasource.addDataTable(poResult.dataSource,this.autoDispatch);
				}else{
//					EDIApplication.outputDebug(""
					Alert.show(poResult.errorInfo,"ds:"+poResult.dsName+"--加载失败..");
				}
			}
		}
		
		protected function faultHandle(event:FaultEvent):void{
			pw.close();
			mx.controls.Alert.show(event.message.toString());
			trace("-----------");
			trace("系统级错误：事件：FaultEvent(当 HTTPService 调用失败时调度) 方法：faultHandle");
			trace(event.message.toString());
			EDIApplication.outputDebug("系统级错误：事件：FaultEvent(当 HTTPService 调用失败时调度) 方法：faultHandle<br/>"+event.message.toString());
			trace("-----------");
			if(proxyPool)
			{
				HttpProxyPool.freeHttpProxy(this);
			}
		}
		
		/**
		 * 提示信息 
		 * @param value
		 * 
		 */		
		public function set tips(value:Array):void{_tips=value;}
		public function get tips():Array{return _tips;}
		
		private function showSucessMessage(event:ResultEvent):void{
			if (successMessage != null && successMessage != ""){
				Alert.show(successMessage);
			}
		}
		
		private function showFailedMessage(event:FaultEvent):void{
			if (failedMessage !=null && failedMessage != ""){
				Alert.show(failedMessage,"错误！");	
			}			
		}
	}
}